Mysql中的索引原理

1. 是什么

官方介绍索引是帮助MySQL高效获取数据数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度, 也就是排序好的快速查询的数据结构

2. 索引的优势和劣势

2.1 优势

  • 可以提高数据检索的效率降低数据库的IO成本,类似于书的目录。 – 检索

  • 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。 –排序

  • 被索引的列会自动进行排序,包括【单列索引】和【组合索引】,只是组合索引的排序要复杂一 些。

  • 如果按照索引列的顺序进行排序,对应order by语句来说,效率就会提高很多。

  • where 索引列 在存储引擎层 处理

2.2 劣势

  • 索引会占据磁盘空间

  • 索引虽然会提高查询效率,但是会降低更新表的效率。比如每次对表进行增删改操作,MySQL不仅要保存数据,还有保存或者更新对应的索引文件。

3. 索引的分类

  • 单列索引

  • 组合索引

  • 全文索引
  • 空间索引

  • 位图索引 oracle

4. 索引的使用

4.1 创建索引

  • 单列索引之普通索引
1
2
CREATE INDEX index_name ON table(column(length)) ;
ALTER TABLE table_name ADD INDEX index_name (column(length)) ;
  • 单列索引之唯一索引

    1
    2
    CREATE UNIQUE INDEX index_name ON table(column(length)) ;
    alter table table_name add unique index index_name(column);
  • 单列索引之全文索引

1
2
CREATE FULLTEXT INDEX index_name ON table(column(length)) ; 
alter table table_name add fulltext index_name(column)
  • 组合索引
1
ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10)) ;

4.2 删除索引

1
DROP INDEX index_name ON table

4.3查看索引

1
SHOW INDEX FROM table_name;

5. 索引原理分析

5.1 索引的存储结构

索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引;

MyIsam和InnoDB存储引擎: 只支持B+Tree索引,也就是说默认使用B+Tree索引,不能够更换

Memory/HEAP存储引擎: 支持HASH和BTree索引

5.2 B树和B+树

B树图示

B树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个 分支,即多叉)平衡查找树。 多叉平衡

  • B树的高度一般都是在2-4这个高度,树的高度直接影响IO的读写次数

  • 如果是三层树结构—支撑的数据可以达到20G,如果是四层树结构—支撑的数据可以达到几十T

    B和B+的区别

    B树和B+树的最大区别在于非叶子节点是否存储数据的问题。

    B树是非叶子节点和叶子节点都会存储数据

    B+树只有叶子节点才会存储数据,而且存储的数据都是在一行上,而且这些数据都是有指针指向 的,也就是有顺序的。

5.3 非聚簇索引(MyISAM)

对于MyISAM存储引擎,也是采用的是B+Tree索引, 由于MyISAM存储引擎,数据和索引是在不同的文件中的,因此不管是否是主键索引,B+Tree索引的叶子节点存储的是数据行的地址,不会存储行数据。

主键索引

辅助索引(次要索引)

5.4 聚簇索引(InnoDB)

对于InnoDB,数据和索引是在一个文件中,InnoDB采用B+Tree索引,叶子节点上存储的是索引和数据,并非地址值。对于聚簇索引的主键索引,叶子节点存储的主键对应的一整行数据,对于非主键索引,叶子节点上存储的是主键值, 如果不是覆盖索引,那么会产生回表,降低查询速度。

对于聚集索引,表示的是数据和索引在一个文件中

主键索引

注意: 叶子节点上的数据都是排序好的,从左到右是顺序排列的

辅助索引

这里,如果对name创建单值索引,叶子节点存储的索引值,然后通过name来信息的时候,如果使用的select *那么此时mysql,会根据叶子节点的主键值,从主键索引中查找的整行的数据。

回表: 从辅助索引中查找到主键, 然后从主键索引中查找数据的过程,被称为”回表

select * from t where name=’Alice’ 给name做了索引找两个索引树

select id,name from t where name=’Alice’ – 只查找了一次索引树,因为在辅助索引中,可以找到所有的数据。所以不需要回表**

形成索引树覆盖索引

覆盖索引,实质就是能够一次性从辅助索引树上,拿到所有的数据,不产生回表的操作。

利用组合索引 完成索引覆盖覆盖

score name 建立成一个索引

# MySql
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×